﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using TCC.ControleFluxoDeCaixa.Model.Contas;
using TCC.ControleFluxoDeCaixa.Model.Fluxo;
using TCC.ControleFluxoDeCaixa.Model.Fluxo.Credito;
using TCC.ControleFluxoDeCaixa.Model.Usuarios;

namespace TCC.ControleFluxoDeCaixa.Model.Entities
{
    public class InicalizadorEntidades : DropCreateDatabaseIfModelChanges<FluxoDeCaixaContext>
    {
        protected override void Seed(FluxoDeCaixaContext context)
        {
            #region Usuarios
            var usuarios = new List<Usuario>
            {
                new Usuario {Nome = "USU 1", Login = "usu1",Senha = "123"},
                new Usuario {Nome = "USU 2", Login = "usu2",Senha = "123"},
                new Usuario {Nome = "USU 3", Login = "usu3",Senha = "123"},
            };

            foreach (var std in usuarios)
                context.Usuarios.Add(std);

            #endregion
            #region Bancos
            var bancos = new List<Banco>
            {
                new Banco {Nome = "Bradesco"},
                new Banco {Nome = "Santander"},
                new Banco {Nome = "HSBC"},
                new Banco {Nome = "BancodoBrasil"}
            };

            foreach (var std in bancos)
                context.Bancos.Add(std);

            #endregion
            #region ContasFinanceiras

            var contasFinanceiras = new List<ContaFinanceira>
            {
                new ContaFinanceira {Nome = "Carteira",Usuario = usuarios[0]},
                new ContaFinanceira {Nome = "Carteira",Usuario = usuarios[1]},
                new ContaFinanceira {Nome = "Carteira",Usuario = usuarios[2]},
            };

            foreach (var std in contasFinanceiras)
                context.ContaFinanceiras.Add(std);

            #endregion
            #region TipoDeContasBancarias
            var tipoDeContasBancarias = new List<TipoDeContaBancaria>
            {
                new TipoDeContaBancaria{Nome = "Conta Corrente"},
                new TipoDeContaBancaria{Nome = "Conta Poupança"},
                new TipoDeContaBancaria{Nome = "Conta Investimento"}, 
            };

            foreach (var std in tipoDeContasBancarias)
                context.TiposContaBancaria.Add(std);
            #endregion
            #region ContasFinanceirasBancarias
            var contasFinanceirasBancarias = new List<ContaFinanceiraBancaria>
            {
                new ContaFinanceiraBancaria{Nome = "Bradesco",Numero = "4566",Banco = bancos[0] ,IsAtiva = true,TipoDeContaBancaria = tipoDeContasBancarias[0],Agencia = "2568-9",Usuario = usuarios[1]},
                new ContaFinanceiraBancaria{Nome = "Santander",Numero = "5555",Banco = bancos[1] ,IsAtiva = true,TipoDeContaBancaria = tipoDeContasBancarias[1],Agencia = "1168-9",Usuario = usuarios[1]},
                new ContaFinanceiraBancaria{Nome = "HSBC",Numero = "6666",Banco = bancos[2] ,IsAtiva = true,TipoDeContaBancaria = tipoDeContasBancarias[2],Agencia = "258-9",Usuario = usuarios[1]},
                new ContaFinanceiraBancaria{Nome = "Banco do Brasil",Numero = "6666",Banco = bancos[3] ,IsAtiva = true,TipoDeContaBancaria = tipoDeContasBancarias[2],Agencia = "258-9",Usuario = usuarios[1]},

            };

            foreach (var std in contasFinanceirasBancarias)
                context.ContaFinanceiraBancarias.Add(std);
            #endregion
            #region Categorias
            var categorias = new List<Categoria>
            {
               new Categoria{Nome = Categoria.CategoriaTransferenciaNome},
               new Categoria{Nome = "Lazer"},
               new Categoria{Nome = "Conta de consumo de casa"},
               new Categoria{Nome = "Aluguél"},
               new Categoria{Nome = "Prestação-Casa-De-Praia"},
               new Categoria{Nome = "Jogos de Futebol"},
               new Categoria{Nome = "Bares"},
               new Categoria{Nome = "Gastronomia"},
               new Categoria{Nome = "Educação"},
               new Categoria{Nome = "Saúde"},
               new Categoria{Nome = "Salário"},
               new Categoria{Nome = "Receita-Férias"},
               new Categoria{Nome = "Empréstimos"},
               new Categoria{Nome = "Viagens"},
               new Categoria{Nome = "Receita-Extra"},
               new Categoria{Nome = "Salário/Doméstica"},
            };

            foreach (var std in categorias)
                context.Categorias.Add(std);
            #endregion
            #region LancamentoRecorrente
            var lancamentoRecorrente = new List<LancamentoRecorrente>
            {
               new LancamentoRecorrente
               {
                   Nome = "Conta de Luz",
                   DataInicio = new DateTime(2015,06,01),Categoria = categorias[2], Conta = contasFinanceirasBancarias[1], ValorEsperadoAbsoluto = 520, TipoDeMovimento = TipoDeMovimento.Despesa,
                   UnidadesDeRecorrencia = {new LancamentoRecorrenteUnidadeTempo{UnidadeTempo = UnidadeTempo.Mes,Valor = 1}}
               },
               new LancamentoRecorrente
               {
                   Nome = "Conta de d'água",
                   DataInicio =new DateTime(2015,06,28),Categoria = categorias[2], Conta = contasFinanceirasBancarias[1],ValorEsperadoAbsoluto= 250, TipoDeMovimento = TipoDeMovimento.Despesa,
                   UnidadesDeRecorrencia = {new LancamentoRecorrenteUnidadeTempo{UnidadeTempo = UnidadeTempo.Mes,Valor = 1}}
               },
               new LancamentoRecorrente
               {
                   Nome = "Conta de gás",
                   DataInicio = new DateTime(2015,06,15), Categoria = categorias[2], Conta = contasFinanceirasBancarias[1], ValorEsperadoAbsoluto= 120, TipoDeMovimento = TipoDeMovimento.Despesa,
                   UnidadesDeRecorrencia = {new LancamentoRecorrenteUnidadeTempo{UnidadeTempo = UnidadeTempo.Mes,Valor = 1}}
               },
               new LancamentoRecorrente
               {
                   Nome = "Conta de Telefone/tv à cabo/internet",
                   DataInicio = new DateTime(2015,06,26), Categoria = categorias[2], Conta = contasFinanceirasBancarias[1], ValorEsperadoAbsoluto= 850, TipoDeMovimento = TipoDeMovimento.Despesa,
                   UnidadesDeRecorrencia = {new LancamentoRecorrenteUnidadeTempo{UnidadeTempo = UnidadeTempo.Mes,Valor = 1}}
               },
               new LancamentoRecorrente
               {
                   Nome = "Aluguél",
                   DataInicio = new DateTime(2015,06,5),Categoria = categorias[3], Conta = contasFinanceirasBancarias[1], ValorEsperadoAbsoluto= 450, TipoDeMovimento = TipoDeMovimento.Despesa,
                   UnidadesDeRecorrencia = {new LancamentoRecorrenteUnidadeTempo{UnidadeTempo = UnidadeTempo.Mes,Valor = 1}}
               },
               new LancamentoRecorrente
               {
                   Nome = "Empregada",
                   DataInicio = new DateTime(2015,06,5),Categoria = categorias[15], Conta = contasFinanceirasBancarias[1], ValorEsperadoAbsoluto= 950, TipoDeMovimento = TipoDeMovimento.Despesa,
                   UnidadesDeRecorrencia = {new LancamentoRecorrenteUnidadeTempo{UnidadeTempo = UnidadeTempo.Mes,Valor = 1}}
               },
                new LancamentoRecorrente
               {
                   Nome = "Prestação-Casa de Praia",
                   DataInicio = new DateTime(2015,06,25),DataFim = new DateTime(2030,08,01), Categoria = categorias[4], Conta = contasFinanceirasBancarias[1], ValorEsperadoAbsoluto= 2550, TipoDeMovimento = TipoDeMovimento.Despesa,
                   UnidadesDeRecorrencia = {new LancamentoRecorrenteUnidadeTempo{UnidadeTempo = UnidadeTempo.Mes,Valor = 1}}
               },
               new LancamentoRecorrente
               {
                   Nome = "Mensalidade Colégio  Cruzeiro/Filho1",
                   DataInicio = new DateTime(2015,06,10),DataFim = new DateTime(2015,12,18), Categoria = categorias[8], Conta = contasFinanceirasBancarias[1], ValorEsperadoAbsoluto = 1500, TipoDeMovimento = TipoDeMovimento.Despesa,
                   UnidadesDeRecorrencia = {new LancamentoRecorrenteUnidadeTempo{UnidadeTempo = UnidadeTempo.Mes,Valor = 1}}
               }, 
               new LancamentoRecorrente
               {
                   Nome = "Mensalidade Colégio  Cruzeiro/Filho2",
                   DataInicio = new DateTime(2015,06,10),DataFim = new DateTime(2015,12,18), Categoria = categorias[8], Conta = contasFinanceirasBancarias[1], ValorEsperadoAbsoluto = 1700, TipoDeMovimento = TipoDeMovimento.Despesa,
                   UnidadesDeRecorrencia = {new LancamentoRecorrenteUnidadeTempo{UnidadeTempo = UnidadeTempo.Mes,Valor = 1}}
               },
               new LancamentoRecorrente
               {
                   Nome = "Salário/BNDES",
                   DataInicio = new DateTime(2015,06,5),DataFim = new DateTime(2015,12,18),Categoria = categorias[10], Conta = contasFinanceirasBancarias[1], ValorEsperadoAbsoluto = 18000, TipoDeMovimento = TipoDeMovimento.Receita,
                   UnidadesDeRecorrencia = {new LancamentoRecorrenteUnidadeTempo{UnidadeTempo = UnidadeTempo.Mes,Valor = 1}}
               },
               new LancamentoRecorrente
               {
                   Nome = "Salário/Professor",
                   DataInicio = new DateTime(2015,06,10),Categoria = categorias[10], Conta = contasFinanceirasBancarias[1], ValorEsperadoAbsoluto = 3500, TipoDeMovimento = TipoDeMovimento.Receita,
                   UnidadesDeRecorrencia = {new LancamentoRecorrenteUnidadeTempo{UnidadeTempo = UnidadeTempo.Mes,Valor = 1}}
               }


            };

            foreach (var recorrente in lancamentoRecorrente)
            {
                context.LancamentosRecorrentes.Add(recorrente);
                foreach (var unidade in recorrente.UnidadesDeRecorrencia) unidade.LancamentoRecorrente = recorrente;
                recorrente.AtualizarListaDeVencimentos();

            }
                
            #endregion
            #region Bandeira/Credito
            var bandeiraCredito = new BandeiraCredito {Nome = "Visa"};
            context.BandeiraCreditos.Add(bandeiraCredito);
            context.ContasCredito.Add(new ContaCredito
            {
                ContaVinculada = contasFinanceirasBancarias[0],
                DiaDoVencimento = 10,
                DigitoVerificador = "888",
                Nome = "Cartao Credito",
                Numero = "1234123412341234",
                QtdDiasPeriodoFechamento = 10,
                TitularDoCartao = "Diogo",
                Usuario = contasFinanceirasBancarias[0].Usuario,
                Validade = new DateTime(2020,1,1),
                ValorAnuidade = 200,
                ValorLimite = 3000,
                Bandeira = bandeiraCredito,
            });
            #endregion
            #region Lancamentos

            var rnd = new Random((int) DateTime.Now.Ticks);

            foreach (var usuario in usuarios)
            {
                var catsDic = new Dictionary<Categoria, string[]>
                {
                    {categorias[1],  new[] {"Playcenter", "Cinema","Boate"}}, // "Lazer"},  
                    {categorias[6],  new[] {"Lapa", "Cerva","happy Hour"}}, // "Bares"},
                    {categorias[7],  new[] {"Sushi","Churrascaria","Rodízio de Pizza", "Porcao"}}, // "Gastronomia"},
                    {categorias[8],  new[] {"Curso de Banco de dados", "Certificacao A", "Cert b", "Treinamento"}}, // "Educação"},
                    {categorias[9],  new[] {"Dentista","Fisio", "Academia"}}, // "Saúde"},
                    {categorias[13], new[] {"Cancun","Orlando","Dubai"}}, //    "Viagens"},
                };
                var catsTipoMovDic = new Dictionary<Categoria, TipoDeMovimento>
                {
                    {categorias[1],  TipoDeMovimento.Despesa}, // "Lazer"},  
                    {categorias[6],  TipoDeMovimento.Despesa}, // "Bares"},
                    {categorias[7],  TipoDeMovimento.Despesa}, // "Gastronomia"},
                    {categorias[8],  TipoDeMovimento.Despesa}, // "Educação"},
                    {categorias[9],  TipoDeMovimento.Despesa}, // "Saúde"},
                    {categorias[10], TipoDeMovimento.Receita}, // "Salário"},
                    {categorias[11], TipoDeMovimento.Receita}, // "Receita-Férias"},
                    {categorias[13], TipoDeMovimento.Despesa}, //    "Viagens"},
                };

                var cats = catsDic.Keys.ToArray();
                var contas = contasFinanceiras.Union(new[]{contasFinanceirasBancarias[1]}).Where(u => u.Usuario == usuario).ToArray();
                

                foreach (var i in Enumerable.Range(1, 12))
                for (int j = 0; j < 10; j++)
                {

                    var cat = cats[rnd.Next(0, cats.Length - 1)];
                
                    var lanc = new Lancamento
                    {
                        Usuario = usuario,
                        Categoria =  cat,
                        DataDoLancamento = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(-i).AddDays(-rnd.Next(1, 31)),
                        Nome = catsDic[cat][rnd.Next(0, catsDic[cat].Length - 1)]
                    };
                    context.Lancamentos.Add(lanc);

                    var mov = new Movimento
                    {
                        Conta = contas.Last(),// contas[rnd.Next(0, contas.Length)],
                        DataDoMovimento = lanc.DataDoLancamento,
                        Lancamento = lanc,
                        Historico = "x",
                        TipoDeMovimento = catsTipoMovDic[cat],
                        ValorAbsoluto = rnd.Next(100, 3600)
                    };
                    context.Movimentos.Add(mov);
                }
            }
            #endregion
            #region Receitas Passadas

            foreach (var i in Enumerable.Range(1, 13))
                {

                    var lanc = new Lancamento
                    {
                        Usuario = usuarios[1],
                        Categoria = categorias[10],
                        DataDoLancamento = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 5).AddMonths(-i),
                        Nome = "Salario"
                    };
                    context.Lancamentos.Add(lanc);

                    var mov = new Movimento
                    {
                        Conta = contasFinanceirasBancarias[1],
                        DataDoMovimento = lanc.DataDoLancamento,
                        Lancamento = lanc,
                        Historico = "x",
                        TipoDeMovimento = TipoDeMovimento.Receita,
                        ValorAbsoluto = 18000
                    };
                    context.Movimentos.Add(mov);
                }
            #endregion

            base.Seed(context);
        }
    }
}
